package com.virtual.repository.common.managers;

import java.util.ArrayList;
import java.util.List;

import com.virtual.repository.common.Constants;
import com.virtual.repository.common.queries.ResultEntity;

/**
 * Class stores information about query execution - which driver executes which
 * query and what is expected result of it. Hierarchical structure.
 * 
 * @author kchaber
 *
 */
public class QueryExecutionResultData {
	
	/**
	 * The expected result object class
	 */
	private Class<?> resultClass;

	/**
	 * The expected collection result class
	 */
	private Class<?> collectionResultClass;
	
	/**
	 * The field name in the parent Object, where the result of the query should be set
	 */
	private String parentObjectFieldName;

	/**
	 * Query result data
	 */
	private ResultEntity queryResult;
	
	/**
	 * The results of the query
	 */
	private List<QueryExecutionResultData> subQueryResults = new ArrayList<>();

	public QueryExecutionResultData(QueryExecutionData execData, ResultEntity resultEntity) {
		this.resultClass = execData.getExpectedResultClass();
		this.collectionResultClass = execData.getExpectedCollectionResultClass();
		this.parentObjectFieldName = execData.getParentObjectFieldName();
		this.queryResult = resultEntity;
	}
	
	/**
	 * @return <code>true</code> if execution data must return collection result or <code>false</code> when not.
	 */
	public boolean isCollectionResult() {
		return this.collectionResultClass != null;
	}
	
	/**
	 * @return <code>true</code> if execution result data has sub query results or <code>false</code> when not.
	 */
	public boolean hasSubResults() {
		return this.subQueryResults != null && !this.subQueryResults.isEmpty();
	}
	
	/**
	 * @return <code>true</code> if execution result data has single result or <code>false</code> when not.
	 */
	public boolean hasSingleResult() {
		return this.queryResult != null && this.resultClass != null;
	}
	
	public Class<?> getResultClass() {
		return resultClass;
	}

	public String getParentObjectFieldName() {
		return parentObjectFieldName;
	}

	public ResultEntity getQueryResult() {
		return queryResult;
	}

	public void setQueryResult(ResultEntity queryResult) {
		this.queryResult = queryResult;
	}

	public List<QueryExecutionResultData> getSubQueryResults() {
		return subQueryResults;
	}

	public void setSubQueryResults(List<QueryExecutionResultData> subQueryResults) {
		this.subQueryResults = subQueryResults;
	}

	public Class<?> getCollectionResultClass() {
		if (this.collectionResultClass != null && this.collectionResultClass.isInterface()) {
			this.collectionResultClass = Constants.DEFAULT_COLLECTION;
		}
		return collectionResultClass;
	}

}